home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / perl / examples / miff < prev    next >
Encoding:
Text File  |  2000-08-24  |  5.6 KB  |  191 lines

  1. #!/usr/app/bin/perl
  2.  
  3. eval 'exec /usr/app/bin/perl  -S $0 ${1+"$@"}'
  4.     if 0; # not running under some shell
  5. # pcg@goof.com
  6. # a fairly complete miff save filter
  7.  
  8. use Gimp;
  9. use Gimp::Fu;
  10. use Gimp::UI;
  11. use Fcntl;
  12.  
  13. # Gimp::set_trace(TRACE_ALL);
  14.  
  15. sub write_layer {
  16.    my($fh,$l)=@_;
  17.    my($w,$h)=($l->width,$l->height);
  18.    my $r = new PixelRgn $l,0,0,$w,$h,0,0;
  19.    print $fh "rows=$h columns=$w\n",
  20.          "matte=", $r->bpp&1 ? "False" : "True", "\n",
  21.          ":\012";
  22.    # inefficient as hell, but "what shells?" ;*>
  23.    for my $y (0..$h-1) {
  24.       print $fh $r->get_rect2(0,$y,$w,1);
  25.    }
  26. }
  27.  
  28. register "file_miff_save",
  29.          "save images as miff (Magick Interchange File Format)",
  30.          "Saves images in the miff (Magick Interchange File Format) format used by the ImageMagick package",
  31.          "Marc Lehmann",
  32.          "Marc Lehmann <pcg\@goof.com>",
  33.          "1999-10-26",
  34.          "<Save>/MIFF",
  35.          "RGB, RGBA, GRAY",    # weird, but no matte for !DirectColour
  36.          [],
  37.          sub {
  38.    my($img,$drawable,$filename) = @_;
  39.    my($new_img,$new_drawable);
  40.    my $export = Gimp::UI::export_image ($new_img=$img, $new_drawable=$drawable, "MIFF",
  41.                                         EXPORT_CAN_HANDLE_GRAY|EXPORT_CAN_HANDLE_RGB|EXPORT_CAN_HANDLE_ALPHA |EXPORT_CAN_HANDLE_LAYERS|EXPORT_CAN_HANDLE_LAYERS_AS_ANIMATION);
  42.    die "export failed" if $export == EXPORT_CANCEL;
  43.    my @layers = $new_img->get_layers;
  44.  
  45.    sysopen FILE,$filename,O_CREAT|O_TRUNC|O_WRONLY or die "Unable to open '$filename' for writing: $!\n";
  46.    my $hdr = eval { $img->parasite_find("gimp-comment")->data };
  47.    $hdr = "   COMMENT: $hdr\n" if $hdr;
  48.    $hdr = <<EOF;
  49. id=ImageMagick
  50. {
  51.    CREATOR: file_miff_save gimp plug-in, see http://www.gimp.org/
  52. $hdr}
  53. EOF
  54.  
  55.    Gimp->tile_cache_ntiles($img->width / Gimp->tile_width + 1);
  56.  
  57.    init Progress "Saving '$filename' as MIFF...";
  58.    my $scene = 0;
  59.    for (@layers) {
  60.       print FILE $hdr,
  61.             "scene=$scene\n",
  62.             "class=", $_->is_rgb ? "DirectClass" : "PseudoClass", "\n";
  63.             #"gamma=", Gimp->gamma, "\n";
  64.       # resolution etc..
  65.       write_layer(*FILE,$_);
  66.       $scene++;
  67.       update Progress $scene/@layers;
  68.    }
  69.    close FILE;
  70.    $new_img->delete if $export == EXPORT_EXPORT;
  71.    ();
  72. };
  73.  
  74. sub read_layer {
  75.    my($img)=shift;
  76.    local $_=shift;
  77.    my($w,$h,$d)=($_->{columns},$_->{rows},$_->{_bpp});
  78.  
  79.    my $l = new Layer $img, $w, $h,
  80.                      (
  81.                         $d == 1 ? GRAY_IMAGE
  82.                       : $d == 2 ? GRAYA_IMAGE
  83.                       : $d == 3 ? RGB_IMAGE
  84.                       : $d == 4 ? RGBA_IMAGE
  85.                       : die "Unsupported image depth ($d channels)\n"
  86.                      ),
  87.                      $_->{scene}, 100, NORMAL_MODE;
  88.  
  89.    $l->add_layer($_->{scene});
  90.  
  91.    my $r = new PixelRgn $l,0,0,$w,$h,1,0;
  92.    seek FILE, $_->{_offset}, 0;
  93.  
  94.    for my $y (0..$h-1) {
  95.       read FILE, $_, $w * $d;
  96.       $r->set_rect2($_,0,$y);
  97.    }
  98.    undef $r;
  99.    $l;
  100. }
  101.  
  102. register "file_miff_load",
  103.          "load miff images (Magick Interchange File Format)",
  104.          "Loads images that were saved in the miff (Magick Interchange File Format) format used by the ImageMagick package",
  105.          "Marc Lehmann",
  106.          "Marc Lehmann <pcg\@goof.com>",
  107.          "1999-09-14",
  108.          "<Load>/MIFF",
  109.          undef,
  110.          [],
  111.          sub {
  112.    my($filename) = @_;
  113.    sysopen FILE,$filename,O_RDONLY or die "Unable to open '$filename' for reading: $!\n";
  114.    my(@scenes);
  115.    my $comment;
  116.    seek FILE, 0, 2; my $filesize = tell FILE; seek FILE, 0, 0;
  117.    local $/ = "\012";
  118.    init Progress "Loading MIFF image from '$filename'...";
  119.    do {
  120.       my %h;
  121.       header:
  122.       while (<FILE>) {
  123.          die "Unexpected end of file while reading from '$filename'\n" if eof;
  124.          while($_ =~ /\S/) {
  125.             if (/:\012$/) {
  126.                last header;
  127.             } elsif (s/^\s*(\w+)=(\S+|"(?:[^\\"]+|\\"|\\)*")//) {
  128.                $h{$1}=$2;
  129.             } elsif (s/\s*\{//) {
  130.                while(!s/([^}]*)}//) {
  131.                   $comment .= $_;
  132.                   $_ = <FILE>;
  133.                   die "Unexpected end of file while reading comment block from '$filename'\n" if eof;
  134.                }
  135.                $comment .= $1;
  136.             } else {
  137.                die "Unparseable header line ($_) while reading '$filename'\n";
  138.             }
  139.          }
  140.       }
  141.  
  142.       die "No ImageMagick header found in '$filename'\n" unless $h{id} eq "ImageMagick";
  143.    
  144.       $h{_bpp} = ($h{class} =~ /PseudoClass/ ? 1 : 3)
  145.               + ($h{matte} =~ /True/i ? 1 : 0);
  146.       $h{_size} = $h{rows} * $h{columns} * $h{_bpp};
  147.       $h{_offset} = tell;
  148.       push @scenes, \%h;
  149.       
  150.       seek FILE, $h{_size}, 1;
  151.       update Progress tell()/$filesize*0.2;
  152.    } while !eof;
  153.  
  154.    my ($w,$h,$d);
  155.    for (@scenes) {
  156.       $w = $_->{columns} if $_->{columns} > $w;
  157.       $h = $_->{rows}    if $_->{rows}    > $h;
  158.       $d = $_->{_bpp}    if $_->{_bpp}    > $d;
  159.    }
  160.  
  161.    my $img = new Image $w, $h, $d >= 3 ? RGB : GRAY;
  162.    $img->set_filename($filename);
  163.    $img->undo_disable;
  164.  
  165.    if ($comment) {
  166.       $comment =~ s/^\s+//s;
  167.       $comment =~ s/\s+$//s;
  168.       $img->parasite_attach (new GimpParasite "gimp-comment", PARASITE_PERSISTENT, $comment);
  169.    }
  170.    # resolution etc..
  171.  
  172.    Gimp->tile_cache_ntiles($w / Gimp->tile_width + 1);
  173.  
  174.    # horrors, reverse, and line-by-line (!!)
  175.    for (@scenes) {
  176.       my $layer = read_layer $img,$_;
  177.       update Progress tell()/$filesize*0.8 + 0.2;
  178.    }
  179.  
  180.    $img->undo_enable;
  181.    $img;
  182. };
  183.  
  184. Gimp::on_query {
  185.    Gimp->register_magic_load_handler("file_miff_load", "miff", "", "0,string,id=ImageMagick");
  186.    Gimp->register_save_handler("file_miff_save", "miff", "");
  187. };
  188.  
  189. exit main;
  190.  
  191.